package com.twinkle.rpc.server.nettyConfig.handler;

import com.twinkle.rpc.common.message.RpcRequest;
import com.twinkle.rpc.common.message.RpcResponse;
import com.twinkle.rpc.server.provider.ServiceProvider;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.AllArgsConstructor;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;

/**
 * @author wxx
 * @version 1.0
 * @create 2024/2/26 16:40
 * 指定对接收消息的处理方式
 * 因为是服务器端，我们知道接受到请求格式是RpcRequest
 * Object类型也行，强制转型就行
 */
@AllArgsConstructor
public class NettyRPCServerHandler extends SimpleChannelInboundHandler<RpcRequest> {
    private ServiceProvider serviceProvider;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcRequest request) throws Exception {
        //接收request,读取并调用服务
        RpcResponse response = getResponse(request);
        ctx.writeAndFlush(response);
        ctx.close();
    }

    private RpcResponse getResponse(RpcRequest request) {
        //得到服务名
        String interfaceName = request.getInterfaceName();
        //获取服务端相应的实现类
        Object service = serviceProvider.getService(interfaceName);
        //反射调用方法
        Method method = null;
        try {
            method = service.getClass().getMethod(request.getMethodName(),request.getParamsType());
            Object invoke = method.invoke(service,request.getParams());
            return RpcResponse.success(invoke);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
            System.out.println("方法执行出错");
            return RpcResponse.fail();
        }

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
